"""
Random Stuff
Copyright (C) 2007 Andrew Briscoe

A module with lots of cruft to it out of others.
"""

__license__ = 'GPL http://www.gnu.org/licenses/gpl.txt'
__author__ = 'Andrew Briscoe <everynothing@gmail.com>'
__version__ = '0.0.1'
__program__ = 'PIGS'

import wx, Server, Client
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver

class PIGSClient(LineReceiver):
    "The PIGS client side protocol."
    
    end = "Connection Closed."
    
    def connectionMade(self):
        "What happens when this client connects."
        
        self.factory.clientReady(self)

    def lineReceived(self, text):
        "What happens when this client gets a message."
        
        self.factory.control.process_packet(text)
        if text == self.end:
            self.transport.loseConnection()
            
    def connectionLost(self, reason):
        "We've lost connection!"
        
        pass
        
class PIGSFactory(ClientFactory):

    protocol = PIGSClient
    
    def __init__(self, control):
        
        self.control = control

    def clientConnectionFailed(self, connector, reason):
        "Connection was lost!"
        
        pass
     
    def clientConnectionLost(self, connector, reason):
        "Connection was lost!"
        
        pass
        
    def clientReady(self, instance):
        "Client was initialized."
        
        self.clientInstance = instance
    
    def send_message(self, array):
        "Send a message."
        
        if hasattr(self, 'clientInstance'):
            self.clientInstance.sendLine( \
                  Server.SEPARATE.join([str(t) for t in array]))

class TwistedProxy(object):
    """ This is a Twisted proxy. Delegate method calls to this object and
    they will be executed by the Twisted event loop in its own thread. """

    def __init__(self, realobj):
        self._target = realobj
        self.enabled = True

    def __getattr__(self, name):
        attr = getattr(self._target, name)
        call = reactor.callFromThread
        if callable(attr):
            # This is the real proxy method we generate on-the-fly
            def fun(*args, **kargs):
                if self.enabled:
                    call(attr, *args, **kargs)
                else:
                    print "TwistedProxy disabled, event discarded"
            setattr(self, name, fun)
            return fun
        raise AttributeError("can only proxy object methods")

    def DisableProxy(self):
        
        self.enabled = False

class UIProxy(object):
    """ This is a wxWidgets proxy. Delegate method calls to this object and
    they will be executed from the wxWidgets event loop in its own thread.

    For this to work you will also have to make your wx.App class inherit
    from the UIProxyReceiver mix-in (it will define the event handler for
    custom proxy events). """

    def __init__(self, realobj):
        self._target = realobj

    def __getattr__(self, name):
        attr = getattr(self._target, name)
        if callable(attr):
            def fun(*args, **kargs):
                if self._target._proxy_enabled:
                    wx.CallAfter(attr, *args, **kargs)
                else:
                    print "UIProxy disabled, event discarded"
            setattr(self, name, fun)
            return fun
        raise AttributeError("can only proxy object methods")
        
def fit_center_show(app, fit=True):
    
    "Fits(if fit) centers and shows app."
    
    if fit:
        app.Fit()
    app.Center()
    app.Show(True)
    
def run_and_install(react, factory):
    "Runs and installs reactor."
    
    react.connectTCP('127.0.0.1', 1025, factory)
    react.run(installSignalHandlers=False)
    
def server_start(react, factory):
    "Start the server reactor."
    
    react.listenTCP(1025, factory)
    react.run()
    
def game_from_strings(game, board, variant='Regular'):
    "Make a game from strings."
    
    import Game
    return Game.Game(possible_games()[game](board_name=board))

def possible_games():
    "What games are there?"
    
    import Chess, Go
    return {'Chess': Chess.Chess, 'Go': Go.Go}

class MyApp(wx.App):
    'Currently tests on a go board.'
    
    def OnInit(self):
        'What happens when main app starts up.'
        
        Client.PIGSClientFrame()
        return True
    
def make_sizer(vertical=True):
    "Make a box sizer."
    
    orient = wx.VERTICAL if vertical else wx.HORIZONTAL
    return wx.BoxSizer(orient)